﻿using System;
using System.ComponentModel;

namespace Slippor.Common.PluginFramework
{
    public class PluginInfo
    {
        public Type PluginType { get; set; }

        public PluginCategory Category { get; set; }

        public string PluginName { get; set; }

        public string DisplayName { get; set; }

        public string PluginFile { get; set; }

        public string PluginDescription { get; set; }

        public bool IsEnabled { get; set; }

        public bool IsConfigable { get { return PluginConfig != null; } }

        public IConfig PluginConfig { get; set; }

        private object _pluginConfiguartion;
        public object PluginConfiguration
        {
            get { return _pluginConfiguartion; }
            set { _pluginConfiguartion = value;}
        }

        public bool IsVersionable { get { return PluginVersion != null && PluginVersion.IsVersionable; } }

        public IVersion PluginVersion { get; set; }

        public PluginAuthor Author { get; set; }

        public static PluginInfo GetPluginInfo(Type type)
        {
            var pInfo = new PluginInfo
            {
                PluginType = type,
                PluginName = type.Name,
                PluginConfiguration = String.Empty
            };
            var descriptionAttribute = (DescriptionAttribute)(TypeDescriptor.GetAttributes(type)[typeof(DescriptionAttribute)]);
            if (descriptionAttribute != null) pInfo.PluginDescription = descriptionAttribute.Description;
            var displayNameAttribute = (DisplayNameAttribute)(TypeDescriptor.GetAttributes(type)[typeof(DisplayNameAttribute)]);
            if (displayNameAttribute != null) pInfo.DisplayName = displayNameAttribute.DisplayName;
            var authorAttribute = (AuthorAttribute)(TypeDescriptor.GetAttributes(type)[typeof(AuthorAttribute)]);
            if (authorAttribute != null) pInfo.Author = authorAttribute.Author;
            var versionAttribute = (VersionAttribute)(TypeDescriptor.GetAttributes(type)[typeof(VersionAttribute)]);
            if (versionAttribute != null) pInfo.PluginVersion = versionAttribute;
            var categoryAttribute = (PluginCategoryAttribute)(TypeDescriptor.GetAttributes(type)[typeof(PluginCategoryAttribute)]);
            if (categoryAttribute != null) pInfo.Category = categoryAttribute.Category;
            var configAttribute = (ConfigAttribute)(TypeDescriptor.GetAttributes(type)[typeof(ConfigAttribute)]);
            if (versionAttribute != null) pInfo.PluginConfig = configAttribute;
            return pInfo;
        }

        public bool Config(ref IPlugin instance)
        {
            if(PluginConfig != null)
            {
                return PluginConfig.Config(ref instance, out _pluginConfiguartion);
            }
            else
            {
                return false;
            }
        }

        public void Update(ref IPlugin instance)
        {
            PluginConfig.Update(ref instance, ref _pluginConfiguartion);
        }
    }

    public enum PluginCategory
    {
        Other = 0,
        Search = 1,
        Filter = 2,
        Handler = 3,
        Tracker = 4,
    }
}